package aduros.display {

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;

import com.threerings.text.TextFieldUtil;

public class ToolTipManager
{
    public var screen :DisplayObjectContainer;
    public var bounds :Rectangle;

    public function ToolTipManager ()
    {
        if (_instance != null) {
            throw new Error("Singleton");
        }
    }

    public static function get instance () :ToolTipManager
    {
        return _instance;
    }

    public function showBy (source :DisplayObject, text :String) :void
    {
        var local :Rectangle = source.getBounds(screen);

        var label :TextField = TextFieldUtil.createField(text,
            { x: PADDING, y: PADDING, textColor: 0x000000,
                selectable: false, autoSize: TextFieldAutoSize.LEFT },
            { font: "_sans", size: 10 });

        clear();

        _toolTip = new Sprite();
        _toolTip.graphics.lineStyle(1, 0xbaba45);
        _toolTip.graphics.beginFill(0xf7f7bf);
        _toolTip.graphics.drawRect(0, 0, label.width+2*PADDING, label.height+2*PADDING);
        _toolTip.graphics.endFill();
        _toolTip.addChild(label);

        var rightX :Number = local.x+local.width;
        var rightY :Number = local.y;
        var belowY :Number = local.y+local.height;
        var aboveY :Number = local.y-_toolTip.height;
        var maxX :Number = bounds.width-_toolTip.width;
        var maxY :Number = bounds.height-_toolTip.height;

        if (rightX > maxX) {
            _toolTip.x = maxX;
            _toolTip.y = (belowY > maxY) ? aboveY : belowY;
        } else {
            _toolTip.x = rightX;
            _toolTip.y = rightY;
        }

        screen.addChild(_toolTip);
    }

    public function clear () :void
    {
        if (_toolTip != null) {
            screen.removeChild(_toolTip);
            _toolTip = null;
        }
    }

    /** Handy function to set up the mouse listeners for showing a tooltip. */
    public function attach (node :InteractiveObject, toolTip :String) :void
    {
        node.addEventListener(MouseEvent.ROLL_OVER, function (event :MouseEvent) :void {
            showBy(node, toolTip);
        });
        node.addEventListener(MouseEvent.ROLL_OUT, function (... _) :void {
            ToolTipManager.instance.clear();
        });
    }

    protected static const PADDING :int = 2;

    protected static var _instance :ToolTipManager = new ToolTipManager();

    protected var _toolTip :Sprite;
}

}
